(** Servers use a listener object to listen on a specific port number. A listener is initialized and started with Listen. The server subsequently uses Requested to determine if a client wishes to connect to the port. If Requested(L) is TRUE, the server accepts the connection request by calling Accept(L, C, res). The server stops a listener object from listening to a port by calling Close(L).
Ideally, the server would poll Requested in an Oberon.Task and from there would create a new Oberon.Task for every accepted connection which would poll Available and AvailToSend for the connection. *)
ELSE (* passive open not completed or completed in error: error *)
L.listening := FALSE;
TCPRelease(NIL, L);
res := NotDone;
END;
ELSE (* no passive open in progress: error *)
res := NotDone;
END;
END Accept;
(** ---------- Connection ---------- *)
(** Connections are opened with Connect. Reading and writing operations are blocking. Available returns the number of bytes that can be read from a connection without blocking. AvailToSend returns the number of bytes that can be sent over a connection without blocking. Connected is TRUE as long as data can be sent over a connection. A connection is closed with Disconnect.
A connection has an associated id number that can be used to refer to a connection (field id). ThisConnection maps id numbers to connection objects. Clients that use Oberon tasks should store the connection id in the task, rather than the connection object proper, to give the garbage collector a chance to collect and possibly finalize connections. It is guaranteed that the same id is never allocated for two different connections during one session. *)